package com.ashin.client;

import com.alibaba.dashscope.aigc.generation.Generation;
import com.alibaba.dashscope.aigc.generation.GenerationResult;
import com.alibaba.dashscope.aigc.generation.models.QwenParam;
import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesis;
import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesisParam;
import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesisResult;
import com.alibaba.dashscope.common.Message;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;

import com.alibaba.dashscope.common.MessageManager;
import com.alibaba.dashscope.utils.JsonUtils;

import com.alibaba.dashscope.utils.Constants;
import com.ashin.util.HttpUtils;
import com.ashin.util.QQUtils;
import com.theokanning.openai.completion.chat.ChatMessage;
import io.github.mzdluo123.silk4j.AudioUtils;
import lombok.extern.slf4j.Slf4j;
import net.mamoe.mirai.internal.deps.okhttp3.OkHttpClient;
import net.mamoe.mirai.internal.deps.okhttp3.Request;
import net.mamoe.mirai.internal.deps.okhttp3.Response;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Component;
import com.alibaba.dashscope.audio.tts.SpeechSynthesizer;
import com.alibaba.dashscope.audio.tts.SpeechSynthesisParam;
import com.alibaba.dashscope.audio.tts.SpeechSynthesisResult;
import com.alibaba.dashscope.audio.tts.SpeechSynthesisAudioFormat;
import com.alibaba.dashscope.common.ResultCallback;
import com.alibaba.dashscope.common.Status;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Component
@Slf4j
public class QianWenClient {
    private  QwenParam param ;
    private Generation gen = new Generation();
    private static final String apiKey = "sk-9801ba49eb08494881958e12cee11d9d";


    //sd参数
    private static final OkHttpClient CLIENT = new OkHttpClient();
    private static final String MODEL = "stable-diffusion-xl";
    private static final String SIZE = "1024*1024";


    public QianWenClient() {
        Constants.apiKey= apiKey;
        param = QwenParam.builder().model(Generation.Models.QWEN_PLUS).messages(new ArrayList<>())
                .resultFormat(QwenParam.ResultFormat.MESSAGE)
                .topP(0.8)
                /* set the random seed, optional, default to 1234 if not set */
                .seed(100)
                .enableSearch(true)
                .build();
    }
    /**生成文本*/
    public String send(List<ChatMessage> prompt) {
        List<Message> messageList = new ArrayList<>();
        //ApiException: {"statusCode":400,"message":"Role of the first message must be in [\u0027system\u0027, \u0027user\u0027]"
        Message systemMsg = Message.builder().role(Role.SYSTEM.getValue()).content("You are a helpful assistant.").build();
        messageList.add(systemMsg);

        //ApiException: {"statusCode":400,"message":"User and assistant need to appear alternately in the message"
        for (int i = 0; i < prompt.size(); i++) {
            ChatMessage chatMessage = prompt.get(i);
            if(StringUtils.isBlank(chatMessage.getContent()))continue;
            if("user".equals(chatMessage.getRole())){
                Message userMsg = Message.builder().role(Role.USER.getValue()).content(chatMessage.getContent()).build();
                messageList.add(userMsg);
            }else{
                Message sysMsg = Message.builder().role(Role.ASSISTANT.getValue()).content(chatMessage.getContent()).build();
                messageList.add(sysMsg);
            }
        }
        param.setMessages(messageList);
        try {
            GenerationResult result = gen.call(param);
            return result.getOutput().getChoices().get(0).getMessage().getContent();
        } catch (NoApiKeyException e) {

        } catch (InputRequiredException e) {

        }
        return "(error)";
    }
    /***生成语音*/
    public String SyncAudioDataToFile(String text, String voiceModel) {
        voiceModel = "sambert-"+voiceModel+"-v1";
        SpeechSynthesizer synthesizer = new SpeechSynthesizer();
        SpeechSynthesisParam param =
                SpeechSynthesisParam.builder()
                        .apiKey(apiKey)
                        .model(voiceModel)
                        .format(SpeechSynthesisAudioFormat.MP3)
                        .text(text)
                        .sampleRate(48000)
                        .build();
        long seconds = new Date().getTime();
        String voiceFileName = "data/voice/"+seconds+".mp3";
        File file = new File(voiceFileName);
        // 调用call方法，传入param参数，获取合成音频
        ByteBuffer audio = synthesizer.call(param);
        try (FileOutputStream fos = new FileOutputStream(file)) {
            fos.write(audio.array());
            return voiceFileName;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }
    /**生成图片*/
    public String genImage(String posPrompt, String negPrompt) throws ApiException, NoApiKeyException, IOException {
        if(posPrompt.trim().length()<20){
            return QQUtils.usagePng;
        }
        if(StringUtils.isBlank(negPrompt))
            negPrompt= "garfield";
        ImageSynthesis is = new ImageSynthesis();
        ImageSynthesisParam param =
                ImageSynthesisParam.builder()
                        .model(QianWenClient.MODEL)
                        .n(1)
                        .size(QianWenClient.SIZE)
                        .prompt(posPrompt)
                        .negativePrompt(negPrompt)
                        .build();

        ImageSynthesisResult result = is.call(param);
        System.out.println(result);
        String localImgPath = "";
        // save image to local files.
        for(Map<String, String> item :result.getOutput().getResults()){
            String paths = new URL(item.get("url")).getPath();
            String[] parts = paths.split("/");
            String fileName = parts[parts.length-1];
            Request request = new Request.Builder()
                    .url(item.get("url"))
                    .build();

            try (Response response = CLIENT.newCall(request).execute()) {
                if (!response.isSuccessful()) {
                    throw new IOException("Unexpected code " + response);
                }
                localImgPath = "data/"+fileName;
                Path file = Paths.get(localImgPath);
                Files.write(file, response.body().bytes());
            }

        }
        return localImgPath;
    }

    public static void main(String[] args){
        QianWenClient qianWenClient = new QianWenClient();
        Constants.apiKey="sk-9801ba49eb08494881958e12cee11d9d";
        //qianWenClient.SyncAudioDataToFile("今天天气怎么样","sambert-zhichu-v1");
//        try {
//            qianWenClient.callWithMessage();
//
//        } catch (NoApiKeyException e) {
//            throw new RuntimeException(e);
//        } catch (InputRequiredException e) {
//            throw new RuntimeException(e);
//        }
//        try {
//            qianWenClient.genImage("Eagle flying freely in the blue sky and white clouds","garfield");
//        } catch (NoApiKeyException e) {
//            throw new RuntimeException(e);
//        } catch (IOException e) {
//            throw new RuntimeException(e);
//        }
        File mp3File = new File("data/voice/1698724715493.mp3");
        try {
            AudioUtils.init(new File("data"));
            File silk =  AudioUtils.mp3ToSilk(mp3File);

        } catch (IOException e) {
        }
        System.out.println( Constants.apiKey.substring(0,2));
        System.exit(0);
    }
    public void callWithMessage()
            throws NoApiKeyException, ApiException, InputRequiredException {
        Generation gen = new Generation();
        MessageManager msgManager = new MessageManager(10);
        Message systemMsg =
                Message.builder().role(Role.SYSTEM.getValue()).content("你是智能助手机器人").build();
        Message userMsg = Message.builder().role(Role.USER.getValue()).content("如何做西红柿炖牛腩？").build();
        msgManager.add(systemMsg);
        msgManager.add(userMsg);
        QwenParam param =
                QwenParam.builder().model(Generation.Models.QWEN_PLUS).messages(msgManager.get())
                        .resultFormat(QwenParam.ResultFormat.MESSAGE)
                        .topP(0.8)
                        .enableSearch(true)
                        .build();
        GenerationResult result = gen.call(param);
        System.out.println(result);
        msgManager.add(result);
        System.out.println(JsonUtils.toJson(result));
        param.setPrompt("不放糖可以吗？");
        param.setMessages(msgManager.get());
        result = gen.call(param);
        System.out.println(result);
        System.out.println(JsonUtils.toJson(result));
    }
}
